import FairyEditor = CS.FairyEditor;
var App = FairyEditor.App;
/**
 * @description 组件面板
 * @description 属性输入支持简单四则运算
 * @author minghui.yan
 */
export class Calculator {
    public add(): void {
        //组件基础属性面板
        const comBasic = App.inspectorView.GetInspector("basic").panel;
        const items = ["x", "y", "width", "height", "scaleX", "scaleY"]
        for (let i = 0; i < items.length; i++) {
            const element = items[i];
            let inputText = comBasic.GetChild(element).asLabel.GetChild("title").asTextInput
            inputText.onFocusOut.AddCapture((event: CS.FairyGUI.EventContext) => {
                const text = inputText.text;
                let num = this.calculate(text);
                inputText.text = `${num}`;
            })
        }
        //组件设计图
        const design = App.inspectorView.GetInspector("designImage").panel;
        const d_items = ["offsetX", "offsetY"];
        for (let i = 0; i < d_items.length; i++) {
            const element = d_items[i];
            let inputText = design.GetChild(element).asLabel.GetChild("title").asTextInput
            inputText.onFocusOut.AddCapture((event: CS.FairyGUI.EventContext) => {
                const text = inputText.text;
                let num = this.calculate(text)
                inputText.text = `${num}`
            })
        }
    }

    /**
     * 解析字符串为四则运算
     * @description 不支持括号提升优先级
     */
    private parse(text: string): string[] {
        text = text.replace(/\s|\t*/g, "");
        const words = text.match(/(\d+(\.\d+)+|\d+|\+|\-|\*|\/)/g);
        if (words.length == 1 && !isNaN(parseFloat(words[0]))) {
            words.unshift('+');
        }
        if (isNaN(parseFloat(words[0]))) {
            words.unshift('0');
        }
        // console.log('解析之后的字符串数组:', words);
        //禁止连续输入数字、运算符
        for (let i = 0, len = words.length; i < len; i++) {
            const word = parseFloat(words[i]);
            const nextWord = parseFloat(words[i + 1]);
            if (isNaN(word) && isNaN(nextWord)) {
                return [];
            }
            else if (!isNaN(word) && !isNaN(nextWord)) {
                return [];
            }
            else {
                
            }
        }
        return words;
    }
    /**
     * 计算四则运算字符串
     */
    private calculate(text: string): number {
        const words = this.parse(text);
        if (words.length < 3) {
            return 0;
        }
        let result: number = 0;
        while (words.length >= 3) {
            const i = words.findIndex(word => {return (word == "*" || word == "/")});
            let left: number, right: number;
            let operator: string;
            if (i > 0) {
                left = parseFloat(words[i - 1]);
                right = parseFloat(words[i + 1]);
                operator = words[i];
            } else {
                const j = words.findIndex(word => {return (word == '+' || word == "-")});
                if (j > 0) {
                    left = parseFloat(words[j - 1]);
                    right = parseFloat(words[j + 1]);
                    operator = words[j];
                } else {
                    throw new Error(`计算数据异常1: ${left}, ${right}, ${operator}}`);
                }
            }
            if (left != null && right != null && operator != null) {
                switch (operator) {
                case "+":
                    result = parseFloat((left + right).toFixed(2));
                    break;
                case "-":
                    result = parseFloat((left - right).toFixed(2));
                    break;
                case "*":
                    result = parseFloat((left * right).toFixed(2));
                    break;
                case "/":
                    result = right == 0 ? 0 : parseFloat((left / right).toFixed(2));
                    break;
                }
                const i = words.indexOf(operator);
                words.splice(i, 2);
                words[i - 1] = `${result}`;
            } else {
                throw new Error(`计算数据异常2: ${left}, ${right}, ${operator}}`);
            }
        }
        return result;
    }
}